package com.moli.iov.notify.communication.template;

import java.util.*;
import java.util.function.Predicate;

/**
 *
 * Communication template builder.
 *
 *
 * @author OAK
 * @version 3.0
 * @since 2019/10/24 16:31 PM.
 *
 */
public class CommunicationBuilder implements ResolveMatcher {

    private volatile CommunicationTemplate communicationTemplate;

    private static volatile CommunicationBuilder builder;

    private CommunicationBuilder(CommunicationTemplate communicationTemplate){
        this.communicationTemplate = communicationTemplate;
    }

    /**
     * According communication template to builder Builder.
     * @param communicationTemplate Communication template.
     * @return builder Builder.
     */
    public static Builder builder(CommunicationTemplate communicationTemplate){
        if(builder == null){
            synchronized(CommunicationBuilder.class){
                if(builder == null){
                    builder = new CommunicationBuilder(communicationTemplate);
                }
            }
        }else{
            builder.communicationTemplate = communicationTemplate;
        }
        return builder;
    }

    /**
     * According to variables compile generate template.
     * @param variables Variables collection.
     * @param <T> Serialization.
     *
     * @return Whether value is not empty return else throws a type not present exception.
     */
    @Override
    public <T> Optional<String> compile(T variables) {
        Predicate<T> predicate = match();
        Objects.requireNonNull(predicate);
        if(predicate.test(variables)){
            return Optional.of(compose(communicationTemplate.create(), variables));
        }
        throw new TypeNotPresentException(variables.getClass().getTypeName(), new RuntimeException());
    }

}
